package org.dftproject.genesis.ui.figures;

import java.net.URL;
import java.text.DateFormat;
import java.util.Date;

import org.dftproject.genesis.core.collections.Collection;
import org.dftproject.genesis.core.collections.CollectionManager;
import org.dftproject.genesis.ui.Activator;
import org.dftproject.genesis.ui.collections.ICollectionHandler;
import org.dftproject.genesis.ui.pages.IPageInput;
import org.dftproject.genesis.ui.pages.PageManager;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

public class CollectionFigure extends Figure {
	
	private static final Color metadataColor = new Color(null, 0xAA, 0xAA, 0xAA); 

	private final Collection collection;
	
	public CollectionFigure(final Collection collection, UniformSizeGroup linkGroup) {
		this.collection = collection;
		
		ToolbarLayout layout = new ToolbarLayout(true);
		layout.setStretchMinorAxis(true);
		setLayoutManager(layout);

		setBorder(new MarginBorder(3, 5, 3, 5));

		HyperlinkFigure link = new HyperlinkFigure(collection.getName());
		Image icon = getCollectionIcon(collection);
		if (icon != null)
			link.setIcon(icon);
		link.setToolTip(new TooltipLabel(collection.getDescription()));
		link.setAlwaysUnderline(false);
		link.addHyperlinkListener(new IHyperlinkListener() {

			public void linkActivated(Object data, int stateMask) {
				ICollectionHandler handler = getCollectionHandler(collection);
				if (handler != null) {
					String pageId = handler.getPageId(collection);
					IPageInput input = handler.getPageInput(collection);
					if (pageId != null && input != null) {
						CollectionManager.getDefault().touchCollection(collection);
						
						IWorkbench workbench = PlatformUI.getWorkbench();
						IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
						IWorkbenchPage workbenchPage = window.getActivePage();
						PageManager.getDefault().openPage(workbenchPage, input, pageId, true, (stateMask & SWT.CTRL) != 0);
					}
				}
			}
			
		});
		add(new UniformSizeContainer(link, linkGroup, false));
		
		Date lastAccessed = collection.getLastAccessed();
		Label lastAccessedLabel = new Label(stringFromDate(lastAccessed));
		lastAccessedLabel.setTextPlacement(PositionConstants.WEST);
		lastAccessedLabel.setTextAlignment(PositionConstants.CENTER);
		lastAccessedLabel.setForegroundColor(metadataColor);
		lastAccessedLabel.setBorder(new MarginBorder(0, 30, 0, 0));
		add(lastAccessedLabel);
		
		CloseButtonFigure closeButton = new CloseButtonFigure();
		closeButton.setFocusTraversable(true);
		closeButton.setBorder(new MarginBorder(0, 5, 0, 0));
		closeButton.setToolTip(new TooltipLabel("Remove this collection"));
		closeButton.addSelectionListener(new ISelectionListener() {

			public void selected() {
				CollectionManager.getDefault().removeCollection(collection);
			}
			
		});
		add(closeButton);
	}
	
	protected static ICollectionHandler getCollectionHandler(Collection collection) {
		String type = collection.getType();

		IExtensionRegistry registry = Platform.getExtensionRegistry();
		IExtensionPoint extensionPoint = registry.getExtensionPoint(Activator.ID, Activator.COLLECTION_HANDLERS_EXTENSION_POINT);
		IExtension[] extensions = extensionPoint.getExtensions();
		for (IExtension extension : extensions) {
			IConfigurationElement[] configElements = extension.getConfigurationElements();
			for (IConfigurationElement configElement : configElements) {
				if (type.equals(configElement.getAttribute("type"))) {
					try {
						Object instance = configElement.createExecutableExtension("class");
						if (instance instanceof ICollectionHandler)
							return (ICollectionHandler) instance;
					} catch (CoreException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}

		return null;
	}
	
	protected static Image getCollectionIcon(Collection collection) {
		String type = collection.getType();

		IExtensionRegistry registry = Platform.getExtensionRegistry();
		IExtensionPoint extensionPoint = registry.getExtensionPoint(Activator.ID, Activator.COLLECTION_HANDLERS_EXTENSION_POINT);
		IExtension[] extensions = extensionPoint.getExtensions();
		for (IExtension extension : extensions) {
			IConfigurationElement[] configElements = extension.getConfigurationElements();
			for (IConfigurationElement configElement : configElements) {
				if (type.equals(configElement.getAttribute("type"))) {
					String iconPath = configElement.getAttribute("icon");
					String plugin = extension.getNamespaceIdentifier();
					return getImageFromPlugin(plugin, iconPath);
				}
			}
		}

		return null;
	}

	protected static Image getImageFromPlugin(String plugin, String iconPath) {		
		Image image = null;
		try {
			ImageDescriptor imageDescriptor = ImageDescriptor.createFromURL(new URL(Platform.getBundle(plugin).getEntry("/"), iconPath));
			image = imageDescriptor.createImage();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return image;
	}
	
	protected String stringFromDate(Date date) {
		if (date == null)
			return "";
		return DateFormat.getDateInstance().format(date);
	}

	public Collection getCollection() {
		return collection;
	}

}
